package com.caineng.zhaobiao.zbapi.service;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alicp.jetcache.anno.Cached;
import com.caineng.zhaobiao.zbapi.controller.paramVo.CaiZhaobiaoVo;
import com.caineng.zhaobiao.zbapi.dao.CaiZhaobiaoDao;
import com.caineng.zhaobiao.zbapi.domain.CaiBaseUserKeyword;
import com.caineng.zhaobiao.zbapi.domain.CaiZhaobiao;
import com.caineng.zhaobiao.zbapi.service.vo.ZhaobiaoVo;
import com.caineng.zhaobiao.zbapi.utils.enums.USER_ACTION;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 招标服务类
 * @author liandyao
 * @date 2022/7/18 15:44
 */
@Slf4j
@Service
public class CaiZhaobiaoService {

    @Autowired
    CaiZhaobiaoDao zhaobiaoDao ;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    CaiBaseUserKeywordService keywordService;

    @Autowired
    HttpServletRequest request;

    /**
     * 自定义查询
     * @param vo
     * @param page
     * @return
     */
    public List<ZhaobiaoVo> findAll(CaiZhaobiaoVo vo, Pageable page) {

        Query query = new Query();
        Criteria criteria = new Criteria();
        //多个条件
        List<Criteria> criteriaList = new ArrayList<Criteria>();
        log.info("===>"+vo.getAreaName());
        Criteria crArea = new Criteria();

        //定位的城市
        if(StrUtil.isNotBlank(vo.getLbsAreaName())){

            Pattern pattern = Pattern.compile("^.*" + vo.getLbsAreaName() + ".*$", Pattern.CASE_INSENSITIVE);
            crArea.orOperator(Criteria.where("areaName").regex(pattern));
        }
        //定位的省份
        if(StrUtil.isNotBlank(vo.getLbsProvinceName())){

            Pattern pattern = Pattern.compile("^.*" + vo.getLbsProvinceName() + ".*$", Pattern.CASE_INSENSITIVE);
            crArea.orOperator(Criteria.where("provinceName").regex(pattern));
        }

        //如果没有定位,用户也没有选择,直接使用ip的位置
        /*if(StrUtil.isBlank(vo.getLbsAreaName()) && StrUtil.isBlank(vo.getLbsProvinceName()) && StrUtil.isBlank(vo.getProvinceName()) && StrUtil.isBlank(vo.getAreaName())
        && StrUtil.isBlank(vo.getProjectName())
        ){
            String ipAddress = AddressUtils.getRealAddressByIP_GEO(request);
            if(StrUtil.isNotBlank(ipAddress)) {
                //String provinceName = ipAddress.split("-")[0];
                String cityName = ipAddress.split("-")[1];

                Pattern pattern = Pattern.compile("^.*" + cityName + ".*$", Pattern.CASE_INSENSITIVE);
                crArea.orOperator(Criteria.where("areaName").regex(pattern));
            }

        }*/
        //定位的地区查询
        if(!crArea.getCriteriaObject().isEmpty()) {
            criteriaList.add(crArea);
        }

        //用户选择的地区
        Criteria areaName = new Criteria();
        if(StrUtil.isNotBlank(vo.getProvinceName()) && StrUtil.isNotBlank(vo.getAreaName())){
            List<String> listProvince = Arrays.asList(vo.getProvinceName().split(","));
            //有多个地区查询
            List<String> listArea = Arrays.asList(vo.getAreaName().split(","));
            //省份和城市的or
            areaName.orOperator(Criteria.where("provinceName").in(listProvince),Criteria.where("areaName").in(listArea));
        }
        else if(StrUtil.isNotBlank(vo.getProvinceName())){
            List<String> listProvince = Arrays.asList(vo.getProvinceName().split(","));
            areaName.andOperator(Criteria.where("provinceName").in(listProvince));
        }
        else if(StrUtil.isNotBlank(vo.getAreaName())) {
            //有多个地区查询
            List<String> listArea = Arrays.asList(vo.getAreaName().split(","));

            areaName.andOperator(Criteria.where("areaName").in(listArea));

        }

        //用户选择地区查询
        if(!areaName.getCriteriaObject().isEmpty()){
            criteriaList.add(areaName);
        }





        if(StrUtil.isNotBlank(vo.getPrecise())){
            //首页导航栏分类查询
            Pattern pattern = Pattern.compile("^.*" + vo.getPrecise() + ".*$", Pattern.CASE_INSENSITIVE);
            Criteria cr=new Criteria();
            cr.orOperator( Criteria.where("precise").regex(pattern) ,Criteria.where("noticeTitle").regex(pattern) ) ;

            criteriaList.add(cr);
        }
        if(StrUtil.isNotBlank(vo.getNoticeType())){

            //如果是其他公告,还需要查询更正公告等
            if(StrUtil.equals("其他公告",vo.getNoticeType())){
                Criteria cr = new Criteria();
                //其他公告查询
                Pattern pattern1 = Pattern.compile("^.*其他.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern2 = Pattern.compile("^.*更正.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern3 = Pattern.compile("^.*延期.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern4 = Pattern.compile("^.*采购.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern5 = Pattern.compile("^.*预审.*$", Pattern.CASE_INSENSITIVE);
                cr.orOperator(
                        Criteria.where("noticeType").regex(pattern1),
                        Criteria.where("noticeType").regex(pattern2),
                        Criteria.where("noticeType").regex(pattern3),
                        Criteria.where("noticeType").regex(pattern4),
                        Criteria.where("noticeType").regex(pattern5)
                );
                criteriaList.add(cr);
            }else{
                //分类查询,招标公告 中标候选人 中标结果 更正公告公示
                Pattern pattern = Pattern.compile("^.*" + vo.getNoticeType() + ".*$", Pattern.CASE_INSENSITIVE);

                criteriaList.add(new Criteria().andOperator(Criteria.where("noticeType").regex(pattern)));
            }


        }
        //项目名称模糊查询
        if(StrUtil.isNotBlank(vo.getProjectName())){
            //首页导航栏分类查询
            Pattern pattern = Pattern.compile("^.*" + vo.getProjectName() + ".*$", Pattern.CASE_INSENSITIVE);
            //项目名称查询
            criteriaList.add(new Criteria().andOperator(Criteria.where("noticeTitle").regex(pattern))) ;
        }
        if(criteriaList.size()>0){
            criteria.andOperator(ArrayUtil.toArray(criteriaList,Criteria.class));
        }

        query.with(page);
        query.addCriteria(criteria) ;

        query.fields().include("areaName").include("provinceName").include("id").include("noticeTitle").include("noticeType").include("precise").include("precise2").include("publishTime").include("viewCount").include("favCount").include("diggCount");

        List<ZhaobiaoVo> list =mongoTemplate.find(query,ZhaobiaoVo.class);
        return list ;

    }

    /**
     * 查询自己的订阅信息
     * @param zb
     * @param page
     * @return
     */
    public List<ZhaobiaoVo> findCustomMade(CaiZhaobiaoVo zb, Pageable page,String userId) {


        CaiBaseUserKeyword keyword = keywordService.getByUserId(userId);
        if(keyword==null){
            return findAll(zb,page);
        }
        Query query = new Query();
        Criteria criteria = new Criteria();

        //多个条件
        List<Criteria> criteriaList = new ArrayList<Criteria>();

        List<String> listKey = keyword.getKeyWord();
        List<String> listCitys = keyword.getAreaName();

        //项目名称
        if(StrUtil.isNotBlank(zb.getProjectName())){

            //首页导航栏分类查询
            Pattern pattern = Pattern.compile("^.*" + zb.getProjectName() + ".*$", Pattern.CASE_INSENSITIVE);
            Criteria kw = new Criteria();
            kw.orOperator( Criteria.where("noticeTitle").regex(pattern),Criteria.where("precise").regex(pattern)) ;

            //项目名称查询
            criteriaList.add(kw) ;

        }else{
            if(listKey!=null && listKey.size()>0){
                Criteria cr = new Criteria();
                List<Criteria> cr2 = new ArrayList<>();
                for(String key:listKey){
                    Pattern pattern = Pattern.compile("^.*"+key+".*$", Pattern.CASE_INSENSITIVE);
                    Criteria c=Criteria.where("noticeTitle").regex(pattern);
                    cr2.add(c);

                }
                cr.orOperator(ArrayUtil.toArray(cr2,Criteria.class));
                criteriaList.add(cr);
            }
        }

        //地区查询
        if(StrUtil.isNotBlank(zb.getAreaName())){
            Criteria cr2 = new Criteria();
            cr2.orOperator(Criteria.where("provinceName").is(zb.getAreaName()),Criteria.where("areaName").is(zb.getAreaName()));
            criteriaList.add(cr2);
        }else{
            if(listKey!=null && listCitys.size()>0){
                Criteria cr = new Criteria();
                Criteria cr2 = new Criteria();
                cr2.orOperator(Criteria.where("provinceName").in(listCitys),Criteria.where("areaName").in(listCitys));
                cr.andOperator(cr2);
                criteriaList.add(cr);
            }
        }



        //分类查询
        if(StrUtil.isNotBlank(zb.getNoticeType())){

            //如果是其他公告,还需要查询更正公告等
            if(StrUtil.equals("其他公告",zb.getNoticeType())){
                Criteria cr = new Criteria();
                //其他公告查询
                Pattern pattern1 = Pattern.compile("^.*其他.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern2 = Pattern.compile("^.*更正.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern3 = Pattern.compile("^.*延期.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern4 = Pattern.compile("^.*采购.*$", Pattern.CASE_INSENSITIVE);
                Pattern pattern5 = Pattern.compile("^.*预审.*$", Pattern.CASE_INSENSITIVE);
                cr.orOperator(
                        Criteria.where("noticeType").regex(pattern1),
                        Criteria.where("noticeType").regex(pattern2),
                        Criteria.where("noticeType").regex(pattern3),
                        Criteria.where("noticeType").regex(pattern4),
                        Criteria.where("noticeType").regex(pattern5)
                );
                criteriaList.add(cr);
            }else{
                //分类查询,招标公告 中标候选人 中标结果 更正公告公示
                Pattern pattern = Pattern.compile("^.*" + zb.getNoticeType() + ".*$", Pattern.CASE_INSENSITIVE);

                criteriaList.add(new Criteria().andOperator(Criteria.where("noticeType").regex(pattern)));
            }


        }

        if(criteriaList.size()>0){
            criteria.andOperator(ArrayUtil.toArray(criteriaList,Criteria.class));
        }

        query.with(page);
        query.addCriteria(criteria) ;
        query.fields().include("areaName").include("provinceName").include("id").include("noticeTitle").include("noticeType").include("precise").include("precise2").include("publishTime").include("viewCount").include("favCount").include("diggCount");

        List<ZhaobiaoVo> list =mongoTemplate.find(query,ZhaobiaoVo.class);
        return list ;

    }

    /**
     * 根据自定义id查询对象
     * @param myId
     * @return
     */
    @Cached(name="ZHAOBIAO:zhaobiaoCache:ById:", key="#myId", expire = 3600*24) //expire 单位秒
    public CaiZhaobiao findByMyId(String myId) {
        CaiZhaobiao param = new CaiZhaobiao();
        param.setId(myId);
        Optional<CaiZhaobiao> one = zhaobiaoDao.findOne(Example.of(param));
        return one.orElse(null);
    }

    /**
     * 将用户行为数+1
     * @param view
     * @param id
     */
    public void addCountInc(USER_ACTION view, String id) {
        //查询对象
        Query query=Query.query(Criteria.where("id").is(id));
        //更新对象
        Update update=new Update();

        //递增$inc
        if(view==USER_ACTION.view){
            update.inc("viewCount");
        }else if(view==USER_ACTION.fav){
            update.inc("favCount");
        }else if(view==USER_ACTION.digg){
            update.inc("diggCount");
        }
        //参数1：查询对象
        //参数2：更新对象
        //参数3：集合的名字或实体类的类型Comment.class
        mongoTemplate.updateFirst(query,update,CaiZhaobiao.class);
    }

    //@Cached(name="ZHAOBIAO:zhaobiaoPropertyCache:ById:", key="#id", expire = 3600*24) //expire 单位秒
    public Map findZbProperty(String id) {
        Map map = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(id)), Map.class,"cai_zhaobiao_property");
        return map ;
    }
}
